package com.hertz.appr.service;

import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;

import com.hertz.appr.dao.IBaseDao;
import com.hertz.appr.pojo.db.Action;
import com.hertz.appr.pojo.db.GuessResult;
import com.hertz.appr.pojo.db.Message;
import com.hertz.appr.pojo.db.PromoteResult;
import com.hertz.appr.pojo.db.Random;
import com.hertz.appr.pojo.db.GuessResult;
import com.hertz.appr.pojo.db.Task;
import com.hertz.appr.service.cmd.v1.ICmdLineService;
import com.hertz.appr.util.Configuration;

public class ResultService {
	private Logger log = Logger.getLogger(ResultService.class);

	private IBaseDao<GuessResult,Long> guessResultDao;
	private IBaseDao<PromoteResult,Long> promoteResultDao;
	private ResultTemplateService resultTemplateService;
	private TaskService taskService;
	private MessageService messageService;
	private ImageService imageService;
	
	/*
	 * 从具备抽奖资格的消息中，抽取中奖者，并将结果写入guess_result表。
	 */
	public List<GuessResult> lotteryResult4Guess(List<Message> msgList, Integer count,Random random) {
		if(msgList == null){
			log.error("can't build result,msgList is null");
		}
		Set<Integer> awardKey = new HashSet<Integer>();
		if(msgList.size() <= count){
			log.info("count >= readyList.size()=" + msgList.size());
			for(int i = 0; i < count; i++){
				awardKey.add(i);
			}
		}else{
			Collections.sort(msgList);
			log.debug("random num = " + random.getNum());
			Integer start = Long.valueOf(random.getNum() % msgList.size()).intValue();
			log.debug("start = " + start);
			for(int i = 0; i < count; i++){
				int index = Long.valueOf((start + i) % msgList.size()).intValue();
				log.debug("index = " + index + " win");
				awardKey.add(index);
			}
		}
		List<GuessResult> resultList = new ArrayList<GuessResult>();
		for(int i = 0; i < msgList.size(); i++){
			Message msg = msgList.get(i);
			GuessResult result = new GuessResult();
			result.setActionId(msg.getActionId());
			result.setProvider(msg.getProvider());
			result.setStatus(null);
			result.setSystemTime(System.currentTimeMillis());
			result.setUid(msg.getUid());
			if(awardKey.contains(i)){
				result.setAward(GuessResult.award_true);
			}else{
				result.setAward(GuessResult.award_false);
			}
			result.setMsgId(msg.getId());
			result.setNick(msg.getNick());
			resultList.add(result);
			saveGuessResult(result);
		}
		return resultList;
	}
	
	public void lotteryResult4Promote(List<PromoteResult> promoteResultList, Integer count, Random random, String logic){
		if(promoteResultList == null){
			log.error("can't build result,msgList is null");
			return;
		}
		Set<Integer> awardKey = new HashSet<Integer>();
		if(promoteResultList.size() <= count){
			log.info("count >= readyList.size()=" + promoteResultList.size());
			for(int i = 0; i < count; i++){
				awardKey.add(i);
			}
		}else{
			Collections.sort(promoteResultList);
			Integer start = 0;//logic = order时，start 从0开始。
			if(StringUtils.isBlank(logic) || logic.equals(ICmdLineService.oLogicRandom)){//默认logic = random
				start = Long.valueOf(random.getNum() % promoteResultList.size()).intValue();
				log.debug("logic = random,start=" + start);
			}
			for(int i = 0; i < count; i++){
				awardKey.add(Long.valueOf((start + i) % promoteResultList.size()).intValue());
			}
		}
		
		for(int i = 0; i < promoteResultList.size(); i++){
			if(i == promoteResultList.size()){
				return;
			}
			PromoteResult pr = promoteResultList.get(i);
			if(awardKey.contains(i)){
				pr.setAward(GuessResult.award_true);
			}else{
				pr.setAward(GuessResult.award_false);
			}
			promoteResultDao.save(pr);
		}
	}
	
	public boolean generateSendPromoteResultTask(Action action,List<PromoteResult> list){
		boolean result = false;
		boolean hasImg = false;
		File resultImg = null;
		if(resultTemplateService.buildPromoteResult2Html(action, list)){
			log.debug("build html result ok");
			if(imageService.html2Img(action.getId())){
				log.debug("html 2 img ok");
				resultImg = imageService.getImgFile(action.getId());
				log.debug("img fileName=" + resultImg.getName());
				hasImg = true;
			}
		}
		if(hasImg){
			log.debug("start new sendResult task");
			Long current = System.currentTimeMillis();
			Task task = new Task();
			task.setActionId(action.getId());
			task.setCreateTime(current);
			task.setImg(resultImg.getName());
			task.setProvider(action.getProvider());
			task.setSourceTid(action.getActionTid());
			task.setStatus(Task.TASK_STATUS_WAIT);
			task.setSystemTime(current);
			task.setToNick(action.getNick());
			task.setToUid(action.getUid());
			task.setType(Task.TASK_TYPE_SEND_RESULT);
			Map<String, Object> data = new HashMap<String, Object>();
			data.put("toUid", action.getUid());
			data.put("aidStr", ActionService.getActionId62Hex(action.getId()));
			data.put("tUrl", Configuration.getProperty(action.getProvider() + ".t.baseurl") + action.getRegTid());
			String msg = resultTemplateService.getTemplateContent(Configuration.getProperty("tempname.send.result"), data);
			task.setMsg(msg);
			taskService.save(task);
			log.debug("end new sendResult task");
			result = true;
		}
		return result;
	}
	
	public boolean generateSendGuessResultTask(Action action,List<GuessResult> list){
		boolean result = false;
		boolean hasImg = false;
		File resultImg = null;
		for(GuessResult gr : list){
			Message msg = messageService.getMsgById(gr.getMsgId());
			gr.setMessage(msg);
		}
		if(resultTemplateService.buildGuessResult2Html(action, list)){
			log.debug("build html result ok");
			if(imageService.html2Img(action.getId())){
				log.debug("html 2 img ok");
				resultImg = imageService.getImgFile(action.getId());
				log.debug("img fileName=" + resultImg.getName());
				hasImg = true;
			}
		}
		if(hasImg){
			log.debug("start new sendResult task");
			Long current = System.currentTimeMillis();
			Task task = new Task();
			task.setActionId(action.getId());
			task.setCreateTime(current);
			task.setImg(resultImg.getName());
			task.setProvider(action.getProvider());
			task.setSourceTid(action.getActionTid());
			task.setStatus(Task.TASK_STATUS_WAIT);
			task.setSystemTime(current);
			task.setToNick(action.getNick());
			task.setToUid(action.getUid());
			task.setType(Task.TASK_TYPE_SEND_RESULT);
			Map<String, Object> data = new HashMap<String, Object>();
			data.put("toUid", action.getUid());
			data.put("aidStr", ActionService.getActionId62Hex(action.getId()));
			data.put("tUrl", Configuration.getProperty(action.getProvider() + ".t.baseurl") + action.getRegTid());
			String msg = resultTemplateService.getTemplateContent(Configuration.getProperty("tempname.send.result"), data);
			task.setMsg(msg);
			taskService.save(task);
			result = true;
			log.debug("end new sendResult task");
		}
		return result;
	}
	
	/**
	 * 生成图片，发送结果。
	 * @param action
	 */
	public void generateSendResultTask(Action action){
		if(action.getType().equals(Action.ACTION_TYPE_GUESS)){
			List<GuessResult> list = getGuessResult(action);
			generateSendGuessResultTask(action, list);
		}else if(action.getType().equals(Action.ACTION_TYPE_PROMOTE)){
			List<PromoteResult> list = getPromoteResult(action);
			generateSendPromoteResultTask(action, list);
		}
		
	}
	
	public void sendResult(Action action,File file) throws Exception{
		
	}
	
	public List<GuessResult> getGuessResult(Action action){
		log.debug("start getGuessResult");
		log.debug(action);
		if(action == null || !action.getStatus().equals(Action.ACTION_STATUS_FINISH)){
			log.info("action == null || action.status != finish");
			return null;
		}
		String hql = "from GuessResult gr where gr.actionId=?";
		return guessResultDao.find(hql, action.getId());
	}
	
	public void deleteResult(Action a){
		String hql = "";
		if(a.getType().equals(Action.ACTION_TYPE_GUESS)){
			hql = "delete from GuessResult as gr where gr.actionId=?";
			guessResultDao.execute(hql, a.getId());
		}else if(a.getType().equals(Action.ACTION_TYPE_PROMOTE)){
			hql = "delete from PromoteResult as pr where pr.actionId=?";
			promoteResultDao.execute(hql, a.getId());
		}
		
	}
	
	public List<PromoteResult> getPromoteResult(Action action){
		log.debug("start getPromoteResult");
		log.debug(action);
		if(action == null || !action.getStatus().equals(Action.ACTION_STATUS_FINISH)){
			log.info("action == null || action.status != finish");
			return null;
		}
		String hql = "from PromoteResult pr where pr.actionId=?";
		return promoteResultDao.find(hql, action.getId());
	}
	
//	public void lotteryResult4Promote(List<Promot>)

	public void saveGuessResult(GuessResult result){
		guessResultDao.save(result);
	}
	
	public void savePromoteResult(PromoteResult result){
		promoteResultDao.save(result);
	}
	
	public IBaseDao<GuessResult, Long> getGuessResultDao() {
		return guessResultDao;
	}

	public void setGuessResultDao(IBaseDao<GuessResult, Long> guessResultDao) {
		this.guessResultDao = guessResultDao;
	}

	public IBaseDao<PromoteResult, Long> getPromoteResultDao() {
		return promoteResultDao;
	}

	public void setPromoteResultDao(IBaseDao<PromoteResult, Long> promoteResultDao) {
		this.promoteResultDao = promoteResultDao;
	}

	public ResultTemplateService getResultTemplateService() {
		return resultTemplateService;
	}

	public void setResultTemplateService(ResultTemplateService resultTemplateService) {
		this.resultTemplateService = resultTemplateService;
	}

	public ImageService getImageService() {
		return imageService;
	}

	public void setImageService(ImageService imageService) {
		this.imageService = imageService;
	}

	public TaskService getTaskService() {
		return taskService;
	}

	public void setTaskService(TaskService taskService) {
		this.taskService = taskService;
	}

	public MessageService getMessageService() {
		return messageService;
	}

	public void setMessageService(MessageService messageService) {
		this.messageService = messageService;
	}
}
